package com.gree.elasticsearch.service;

import com.gree.elasticsearch.dao.BarRepository;
import com.gree.elasticsearch.domain.Bar;
import com.gree.elasticsearch.exception.NoRollbackException;
import com.gree.elasticsearch.exception.RollbackException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * 总有刁民想害朕，请叫我小花狗
 * create by zxw on 2020/5/21
 */
@Service
public class DefaultBarService {

    private Logger log = LoggerFactory.getLogger(DefaultBarService.class.getName());

    private String rollbackClassName = RollbackException.class.getName();

    @Autowired
    private BarRepository barRepository;

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private BoolService boolService;

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.SERIALIZABLE, rollbackFor =
            {RollbackException.class})
    public Bar getBarById(Integer id) {
        return barRepository.findById(id).map(bar -> {
            log.debug("barRepository.findById. bar is {}", bar);
            return bar;
        }).orElseGet(() -> {
            Bar bar = new Bar("test-bar");
            Bar savedBar = barRepository.save(bar);
            log.debug("barRepository.saveBar, and orEleseGet bar is {}", savedBar);
            return savedBar;
        });
    }

    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}, isolation = Isolation
            .READ_UNCOMMITTED,noRollbackFor = {NoRollbackException.class})
    public void createBar() {
        Bar bar = new Bar();
        bar.setBar(Thread.currentThread().getName());
        barRepository.save(bar);
        Error error;
        Exception exception;
        try {
            throw new Error("error");
        } catch (Throwable t) {
            String errorMsg = t.getMessage();
            log.debug("errorMsg is {}", errorMsg);
        }
    }

    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ)
    public List<Bar> getAllBar() {
        List<Bar> bars = barRepository.findAll();
        bars.stream().forEach(bar -> {
            log.debug("bars.foreach is {}", bar);
        });

        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        bars = barRepository.findAll();
        bars.stream().forEach(bar -> {
            log.debug("bars.foreach is {}", bar);
        });

        return bars;
    }

    @Transactional(propagation = Propagation.NESTED)
    public void createBarByTemplate() {
        jdbcTemplate.execute("insert into bar(bar) values('baba')");
    }
}
